package com.langshixiaobai.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.langshixiaobai.eneity.User;
import com.langshixiaobai.game.*;
import com.langshixiaobai.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.w3c.dom.Text;

import java.io.IOException;

//连接游戏大厅
@Component
public class GameApi extends TextWebSocketHandler {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private RoomManager roomManager;

    @Autowired
    private OnlineUserMap onlineUserMap;

    @Autowired
    private UserMapper userMapper;


    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws IOException {
        GameReadyResponse response = new GameReadyResponse();
        User user = (User) session.getAttributes().get("user");
        //验证当前是否存在会话
        if (user == null) {
            response.setOk(false);
            response.setReason("用户未登入");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            session.close();
            return;
        }
        //之间Matcher中将房间和用户加入到房间管理器中
        //通过从管理器存储的id拿去房间信息，如果没有则用户没进入房间
        Room room = roomManager.getRoomIdByUserId(user.getUserId());

        //用户没有进入房间
        if (room == null) {
            response.setOk(false);
            response.setReason("用户未匹配到");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        if (onlineUserMap.getFromGameHall(user.getUserId()) != null
                || onlineUserMap.getFromGameRoom(user.getUserId()) != null) {
            response.setOk(false);
            response.setReason("禁止多开");
            response.setReason("禁止多开");
            response.setMessage("repeatLogin");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        synchronized (room) {
            //放入存储
            onlineUserMap.enterGameRoom(user.getUserId(), session);
            //添加第一个进入房间的用户
            if (room.getUser1() == null) {
                room.setUser1(user);
                //将第一个进入的用户设为白棋
                room.setWhiteUser(user.getUserId());
                System.out.println("用户: " + room.getUser1() + "进入房间");
                return;
            }
            //添加第二个进入房间的用户
            if (room.getUser2() == null) {
                room.setUser2(user);
                //向前端进行通知
                notifyGameReady(room, room.getUser1(), room.getUser2());
                notifyGameReady(room, room.getUser2(), room.getUser1());
                //打印到控制台
                System.out.println("用户: " + room.getUser2() + "进入房间");
                return;
            }
            //房间满的时候，返回错误信息
            response.setOk(false);
            response.setReason("房间已满");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    public void notifyGameReady(Room room, User thisUser, User thatUser) throws IOException {
        //根据userId获取对应的session进行发送消息
        WebSocketSession session = onlineUserMap.getFromGameRoom(thisUser.getUserId());
        try {
            //进行通知
            GameReadyResponse response = new GameReadyResponse();
            response.setOk(true);
            response.setRoomId(room.getRoomId());
            response.setWhiteUser(room.getWhiteUser());
            response.setMessage("gameReady");
            response.setThisUserId(thisUser.getUserId());
            response.setThatUserId(thatUser.getUserId());
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            System.out.println("已向: " + thisUser + "发送消息");
        } catch (IOException e) {
            MessageResponse response = new MessageResponse();
            response.setOK(false);
            response.setReason("出现错误");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }


    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

        //获取用户信息
        User user = (User) session.getAttributes().get("user");
        //获取用户对应的房间
        Room room = roomManager.getRoomIdByUserId(user.getUserId());

        //添加棋子
        room.putChess(message.getPayload());

        //打印棋盘
        room.printChess();


    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            return;
        }
        WebSocketSession session1 = onlineUserMap.getFromGameRoom(user.getUserId());
        if (session1 == session) {
            onlineUserMap.removeGameRoom(user.getUserId());
        }
        System.out.println("连接出现错误");
        //断开连接，对方获胜，进行获胜通知
        notifyUser(user);

    }


    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        User user = (User) session.getAttributes().get("user");

        if (user == null) {
            return;
        }
        WebSocketSession session1 = onlineUserMap.getFromGameRoom(user.getUserId());
        //判断是否是当前用户，防止多开
        if (session1 == session) {
            onlineUserMap.removeGameRoom(user.getUserId());
        }
        System.out.println("关闭连接");
        //断开连接，对方获胜，进行获胜通知
        notifyUser(user);
    }


    //User user是断开连接的用户
    public void notifyUser(User user) throws IOException {

        Room room = roomManager.getRoomIdByUserId(user.getUserId());
        if (room == null) {
            System.out.println("当前房间已经被释放掉，无需通知");
            return;
        }
        //获胜userId
        Integer userId = user.getUserId() == room.getUser1().getUserId() ? room.getUser2().getUserId() : room.getUser1().getUserId();
       //存储到数据库中
        userMapper.updateWinner(userId);
        //存储输方信息
        userMapper.updateLoser(user.getUserId());

        WebSocketSession session = onlineUserMap.getFromGameRoom(userId);
        //相应
        GameResponse response = new GameResponse();
        //获胜方
        response.setWinner(userId);

        response.setMessage("对方断开连接，获得胜利");
        //发送消息
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        roomManager.removeRoom(room.getRoomId(), room.getUser1().getUserId(), room.getUser2().getUserId());

    }
}
